/**
 *  @file HttpClient.h
 */
#ifndef _HTTPCLIENT_H_
#define _HTTPCLIENT_H_

#include "HttpEndPoint.h"
#include "../../collections/ArrayT.h"

namespace cppflib
{

namespace collections { class BinBuf; }
namespace io { class Stream; }

namespace net
{

namespace http
{

class HttpRequest;
class HttpResponse;

/**
 *  Interface to get pipelined responses
 */
class _DLLAPI IPipelinedResponses : public BaseObject
{
protected:
   IPipelinedResponses() { }

public:
   virtual ~IPipelinedResponses() { }
   virtual HttpResponse * GetResponse() = 0;
};

/**
 *  A client side HTTP end point
 */
class _DLLAPI HttpClient : public HttpEndPoint
{
private:
    HttpRequest *pRequest;

private:
    HttpClient(void);

    void ReplacePreviousRequest(HttpRequest *pNewReq);
   
    void InitSocket();
    void EstablishProxySSLTunnel();
    void ConnectServer();

    void SendRequestLine();
    void SendRequest();

    HttpResponse * ParseStatusLine();
    HttpResponse * GetResponse(io::Stream * pReadStream = NULL);
    void CloseConnectionIfRequired(HttpResponse &res);

protected:
    virtual void InitDefaultHeaders(HttpMessage &httpMsg);

public:
    explicit HttpClient(HttpParams * pParams);
    virtual ~HttpClient(void);

    HttpResponse * IssueRequest(HttpRequest *pNewReq);
    IPipelinedResponses * IssuePipelinedRequests(collections::ArrayCppObjT<HttpRequest> & requests);

    friend class PipelinedResponses;
};

} // end of namespace http

} // end of namespace net

} // end of namespace cppflib


#endif
